#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "cdefs.h"
#include "chash.h"

#define FAIL(str, line) {                    	\
  printf("Fail on line %d: [%s]\n", line, str); \
  return str;                                   \
}

#define ASSERT(expr) {					\
  static_num_tests++;                   \
  if (!(expr)) FAIL(#expr, __LINE__);   \
}

#define RUN_TEST(test) { 		\
	const char *msg = test(); 	\
  	if(msg)					 	\
		return msg; 			\
}
  

static int static_num_tests = 0;

const char *test_chash()
{
	chash_kstr_t htbl;
	ASSERT(chash_kstr_init(&htbl, 2, free) == 0);

	ASSERT(chash_kstr_insert(&htbl, "1", strdup("1")) == 0);
	ASSERT(htbl.htbl.size == 1);
	ASSERT(htbl.htbl.buckets == 2);
	
	ASSERT(chash_kstr_insert(&htbl, "2", strdup("2")) == 0);
	ASSERT(htbl.htbl.size == 2);
	ASSERT(htbl.htbl.buckets == 4);
	
	ASSERT(chash_kstr_insert(&htbl, "3", strdup("3")) == 0);
	ASSERT(htbl.htbl.size == 3);
	ASSERT(htbl.htbl.buckets == 8);
	//ASSERT(chash_kstr_insert(&htbl, "4", "4") == 0);


	char *data;
	ASSERT(chash_kstr_lookup(&htbl, "1", (void **)&data) == 0);
	ASSERT(strcmp(data, "1") == 0);

	ASSERT(chash_kstr_lookup(&htbl, "2", (void **)&data) == 0);
	ASSERT(strcmp(data, "2") == 0);

	ASSERT(chash_kstr_lookup(&htbl, "3", (void **)&data) == 0);
	ASSERT(strcmp(data, "3") == 0);

	ASSERT(chash_kstr_lookup(&htbl, "4", (void **)&data) != 0);


	chash_kstr_destroy(&htbl);
	
    return NULL;
}


static const char *run_all_tests(void)
{
    RUN_TEST(test_chash);
    return NULL;
}

int main(void)
{
    const char *fail_msg = run_all_tests();
    printf("%s, tests run: %d\n", fail_msg ? "FAIL" : "PASS", static_num_tests);
    return fail_msg == NULL ? 0 : -1;
}


